using System;
using System.Collections.Generic;
using Firestarter.Test.Base;
using FireStarterModeller.BO;
using Habanero.Base;
using Habanero.BO;
using NUnit.Framework;

namespace FireStarterModeller.Test.BO
{
    [TestFixture]
    public class TestDMRelationshipOnetoOneAndManytoOnePropKeyRule
    {
        [SetUp]
        public void SetupTest()
        {
            //Runs every time that any testmethod is executed
            TestUtilsDomain.SetupTest();
            BORegistry.DataAccessor = new DataAccessorInMemory();
        }

        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            //Code that is executed before any test is run in this class. If multiple tests
            // are executed then it will still only be called once.
            TestUtilsDomain.SetupFixture();
        }

        [TearDown]
        public void TearDownTest()
        {
            //runs every time any testmethod is complete
        }

        #region DMRelationshipOnetoOneAndManytoOnePropKeyRule

        //At least one side of the relationship must be a PK or AK
        //Single-to-single must be PK to AK(FK)

        [Test]
        public void Test_CreateDMRelationshipOnetoOneAndManytoOnePropKeyRule()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsDMClass.CreateUnsavedDefaultDMClass();
            DMRelationship dmRelationship = dmClass.OwnerRelationships.CreateBusinessObject();
            dmRelationship.Cardinality = Cardinality.Multiple;
            //---------------Assert Precondition----------------
             Assert.AreEqual(Cardinality.Multiple, dmRelationship.Cardinality);
            //---------------Execute Test ----------------------
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Test Result -----------------------
            Assert.IsNotNull(rule);
            Assert.AreEqual("DMRelationshipOnetoOneAndManytoOnePropKeyRule", rule.Name);
            Assert.AreEqual(ErrorLevel.Warning, rule.ErrorLevel);
        }

        [Test]
        public void Test_CreateDMRelationshipOnetoOneAndManytoOnePropKeyRule_NoClassDM()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsDMClass.CreateUnsavedDefaultDMClass();
            DMRelationship dmRelationship = dmClass.OwnerRelationships.CreateBusinessObject();
            dmRelationship.Cardinality = Cardinality.Multiple;
            dmRelationship.ClassDM = null;
            //---------------Assert Precondition----------------
             Assert.AreEqual(Cardinality.Multiple, dmRelationship.Cardinality);
             Assert.IsNull(dmRelationship.ClassDM);
            //---------------Execute Test ----------------------
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsNotNull(rule);
            Assert.AreEqual("DMRelationshipOnetoOneAndManytoOnePropKeyRule", rule.Name);
            Assert.AreEqual(ErrorLevel.Warning, rule.ErrorLevel);
            StringAssert.Contains(string.Format("The Properties associated with both sides of the One to One/Many to One relationship '{0}-{1}' on Classes '{2}-{3}' must be a Primary Key or Alternate Key.", dmRelationship, dmRelationship.ReverseRelationship, dmRelationship.ClassDM, dmRelationship.RelatedClass), rule.Message);
        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_MultipleNoRelationshipProps_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty();
            DMClass dmClass = (DMClass) dmProperty.Class;
            DMRelationship dmRelationship = new DMRelationship();
            dmRelationship.Cardinality = Cardinality.Multiple;
            dmClass.OwnerRelationships.Add(dmRelationship);
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNull(dmClass.ObjectIdentity);
            Assert.AreEqual(0, dmRelationship.RelationshipProperties.Count);
            Assert.AreEqual(Cardinality.Multiple, dmRelationship.Cardinality);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_SingleNoRelationshipProps_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty();
            DMClass dmClass = (DMClass) dmProperty.Class;
            DMRelationship dmRelationship = new DMRelationship();
            dmRelationship.Cardinality = Cardinality.Single;
            dmClass.OwnerRelationships.Add(dmRelationship);
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNull(dmClass.ObjectIdentity);
            Assert.AreEqual(0, dmRelationship.RelationshipProperties.Count);
            Assert.AreEqual(Cardinality.Single, dmRelationship.Cardinality);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

//        [Test]
//        public void Test_CreateDMRelationshipOnetoOneAndManytoOnePropKeyRule_WhenRelationshipNull_ShouldRaiseError()
//        {
//            //---------------Set up test pack-------------------
//            //---------------Assert Precondition----------------
//            //---------------Execute Test ----------------------
//            try
//            {
//                new DMRelationshipOnetoOneAndManytoOnePropKeyRule(null);
//                Assert.Fail("expected ArgumentNullException");
//            }
//            //---------------Test Result -----------------------
//            catch (ArgumentNullException ex)
//            {
//                StringAssert.Contains("Value cannot be null", ex.Message);
//                StringAssert.Contains("dmRelationship", ex.ParamName);
//            }
//        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_MultipleWhenNotInPKOrAK_ShouldFail()
        {
            //---------------Set up test pack-------------------
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty();
            DMClass dmClass = (DMClass) dmProperty.Class;
            DMRelationship dmRelationship = new DMRelationship();
            dmRelationship.Cardinality = Cardinality.Multiple;
            dmClass.OwnerRelationships.Add(dmRelationship);
            DMRelationshipProperty relationshipProperty = new DMRelationshipProperty();
            relationshipProperty.Property = dmProperty;
            dmRelationship.RelationshipProperties.Add(relationshipProperty);
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNull(dmClass.ObjectIdentity);
            Assert.AreEqual(0, dmClass.UniqueConstraints.Count);
            Assert.AreEqual(Cardinality.Multiple, dmRelationship.Cardinality);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsFalse(isValid);
            TestUtilsShared.AssertStringNotEmpty(rule.Message, "rule.Message");
        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_SingleWhenSingleReverse_AndNotInPKOrAK_ShouldFail()
        {
            //---------------Set up test pack-------------------
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty();
            DMClass dmClass = (DMClass) dmProperty.Class;
            DMRelationship dmRelationship = dmClass.OwnerRelationships.CreateBusinessObject();
            dmRelationship.Cardinality = Cardinality.Single;
            dmRelationship.ReverseRelationship.Cardinality = Cardinality.Single;

            DMRelationshipProperty relationshipProperty = new DMRelationshipProperty();
            relationshipProperty.Property = dmProperty;
            dmRelationship.RelationshipProperties.Add(relationshipProperty);
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNull(dmClass.ObjectIdentity);
            Assert.AreEqual(0, dmClass.UniqueConstraints.Count);
            Assert.AreEqual(Cardinality.Single, dmRelationship.Cardinality);
            Assert.AreEqual(Cardinality.Single, dmRelationship.ReverseRelationship.Cardinality);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsFalse(isValid);
            TestUtilsShared.AssertStringNotEmpty(rule.Message, "rule.Message");
        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_SingleWhenSingleReverse_MultipleWhenInPK_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = CreateClassWithPKAndRelationship();
            DMRelationship dmRelationship = dmClass.OwnerRelationships.CreateBusinessObject();
            dmRelationship.Cardinality = Cardinality.Single;
            dmRelationship.ReverseRelationship.Cardinality = Cardinality.Single;
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmClass.ObjectIdentity);
            Assert.AreEqual(0, dmClass.UniqueConstraints.Count);
            Assert.AreEqual(Cardinality.Single, dmRelationship.Cardinality);
            Assert.AreEqual(Cardinality.Single, dmRelationship.ReverseRelationship.Cardinality);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_SingleWhenSingleReverse_WhenInAK_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = CreateClassWithAKAndRelationship();
            DMRelationship dmRelationship = dmClass.OwnerRelationships.CreateBusinessObject();
            dmRelationship.Cardinality = Cardinality.Single;
            dmRelationship.ReverseRelationship.Cardinality = Cardinality.Single;
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNull(dmClass.ObjectIdentity);
            Assert.AreEqual(1, dmClass.UniqueConstraints.Count);
            Assert.AreEqual(Cardinality.Single, dmRelationship.Cardinality);
            Assert.AreEqual(Cardinality.Single, dmRelationship.ReverseRelationship.Cardinality);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_SingleWhenSingleReverse_WhenInInheritedPK_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty();
            DMClass superClass = (DMClass) dmProperty.Class;
            superClass.CreateObjectIdentity(dmProperty);
            DMClass subClass = new DMClass();
            DMInheritanceRelationship inheritanceRelationship = new DMInheritanceRelationship();
            inheritanceRelationship.SuperClass = superClass;
            subClass.InheritanceSuperClassRelationship = inheritanceRelationship;

            DMRelationship dmRelationship = subClass.OwnerRelationships.CreateBusinessObject();
            dmRelationship.Cardinality = Cardinality.Single;
            dmRelationship.ReverseRelationship.Cardinality = Cardinality.Single;

            DMRelationshipProperty relationshipProperty = dmRelationship.RelationshipProperties.CreateBusinessObject();
            relationshipProperty.Property = dmProperty;

            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNull(subClass.ObjectIdentity);
            Assert.IsNotNull(superClass.ObjectIdentity);
            Assert.AreEqual(0, subClass.UniqueConstraints.Count);
            Assert.AreEqual(0, superClass.UniqueConstraints.Count);
            Assert.AreEqual(Cardinality.Single, dmRelationship.Cardinality);
            Assert.AreEqual(Cardinality.Single, dmRelationship.ReverseRelationship.Cardinality);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_SingleWhenSingleReverse_WhenInInheritedAK_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty();
            DMClass superClass = (DMClass) dmProperty.Class;
            superClass.CreateUnsavedUniqueConstraint(new List<DMProperty> { dmProperty });

            DMClass subClass = new DMClass();
            DMInheritanceRelationship inheritanceRelationship = new DMInheritanceRelationship();
            inheritanceRelationship.SuperClass = superClass;
            subClass.InheritanceSuperClassRelationship = inheritanceRelationship;

            DMRelationship dmRelationship = subClass.OwnerRelationships.CreateBusinessObject();
            dmRelationship.Cardinality = Cardinality.Single;
            dmRelationship.ReverseRelationship.Cardinality = Cardinality.Single;

            DMRelationshipProperty relationshipProperty = dmRelationship.RelationshipProperties.CreateBusinessObject();
            relationshipProperty.Property = dmProperty;

            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, subClass.UniqueConstraints.Count);
            Assert.AreEqual(1, superClass.UniqueConstraints.Count);
            Assert.AreEqual(Cardinality.Single, dmRelationship.Cardinality);
            Assert.AreEqual(Cardinality.Single, dmRelationship.ReverseRelationship.Cardinality);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_SingleWhenNoReverse_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty();
            DMClass dmClass = (DMClass) dmProperty.Class;
            DMRelationship dmRelationship = new DMRelationship();
            dmRelationship.Cardinality = Cardinality.Single;
            dmClass.OwnerRelationships.Add(dmRelationship);
            DMRelationshipProperty relationshipProperty = new DMRelationshipProperty();
            relationshipProperty.Property = dmProperty;
            dmRelationship.RelationshipProperties.Add(relationshipProperty);
            dmRelationship.ReverseRelationship = null;
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNull(dmClass.ObjectIdentity);
            Assert.AreEqual(0, dmClass.UniqueConstraints.Count);
            Assert.AreEqual(Cardinality.Single, dmRelationship.Cardinality);
            Assert.IsNull(dmRelationship.ReverseRelationship);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }
        /// <summary>
        /// If single with a Multiple reverse (i.e. M:1) should always pass since the rule will be checked
        /// via the Multiple Relationship.
        /// </summary>
        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_SingleWhenMultipleReverse_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty();
            DMClass dmClass = (DMClass) dmProperty.Class;
            DMRelationship dmRelationship = new DMRelationship {Cardinality = Cardinality.Single};
            dmClass.OwnerRelationships.Add(dmRelationship);
            DMRelationshipProperty relationshipProperty = new DMRelationshipProperty {Property = dmProperty};
            dmRelationship.RelationshipProperties.Add(relationshipProperty);
            dmRelationship.ReverseRelationship.Cardinality = Cardinality.Multiple;
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNull(dmClass.ObjectIdentity);
            Assert.AreEqual(0, dmClass.UniqueConstraints.Count);
            Assert.AreEqual(Cardinality.Single, dmRelationship.Cardinality);
            Assert.IsNotNull(dmRelationship.ReverseRelationship);
            Assert.AreEqual(Cardinality.Multiple, dmRelationship.ReverseRelationship.Cardinality);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }
        
        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_SingleWhenSingleReverse_BothInAK_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = CreateClassWithAKAndRelationship();
            DMRelationship dmRelationship = dmClass.OwnerRelationships[0];
            DMClass relatedClass = CreateClassWithAKAndRelationship();
            SetReverseRelationship(dmRelationship, relatedClass.OwnerRelationships[0]);
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNull(dmClass.ObjectIdentity);
            Assert.IsNull(relatedClass.ObjectIdentity);
            Assert.AreEqual(1, dmClass.UniqueConstraints.Count);
            Assert.AreEqual(1, relatedClass.UniqueConstraints.Count);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        private static void SetReverseRelationship(DMRelationship dmRelationship, DMRelationship reverseRelationship)
        {
            dmRelationship.Relationships.SetRelatedObject("ReverseRelationship", reverseRelationship);
        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_SingleWhenSingleReverse_HasBothPK_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = CreateClassWithPKAndRelationship();
            DMRelationship dmRelationship = dmClass.OwnerRelationships[0];
            DMClass relatedClass = CreateClassWithPKAndRelationship();
            SetReverseRelationship(dmRelationship, relatedClass.OwnerRelationships[0]);
//            dmRelationship.ReverseRelationship = relatedClass.OwnerRelationships[0];
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmClass.ObjectIdentity);
            Assert.IsNotNull(relatedClass.ObjectIdentity);
            Assert.AreEqual(Cardinality.Single, dmRelationship.Cardinality);
            Assert.AreEqual(Cardinality.Single, dmRelationship.ReverseRelationship.Cardinality);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_SingleWhenSingleReverse_HasPKAndRelatedAK_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = CreateClassWithPKAndRelationship();
            DMRelationship dmRelationship = dmClass.OwnerRelationships[0];
            DMClass relatedClass = CreateClassWithAKAndRelationship();
            SetReverseRelationship(dmRelationship, relatedClass.OwnerRelationships[0]);
//            dmRelationship.ReverseRelationship = relatedClass.OwnerRelationships[0];
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmClass.ObjectIdentity);
            Assert.IsNull(relatedClass.ObjectIdentity);
            Assert.AreEqual(1, relatedClass.UniqueConstraints.Count);
            Assert.AreEqual(Cardinality.Single, dmRelationship.Cardinality);
            Assert.AreEqual(Cardinality.Single, dmRelationship.ReverseRelationship.Cardinality);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_SingleWhenSingleReverse_HasAKAndRelatedPK_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = CreateClassWithAKAndRelationship();
            DMRelationship dmRelationship = dmClass.OwnerRelationships[0];
            DMClass relatedClass = CreateClassWithPKAndRelationship();
            SetReverseRelationship(dmRelationship, relatedClass.OwnerRelationships[0]);
//            dmRelationship.ReverseRelationship = relatedClass.OwnerRelationships[0];
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(relatedClass.ObjectIdentity);
            Assert.IsNull(dmClass.ObjectIdentity);
            Assert.AreEqual(1, dmClass.UniqueConstraints.Count);
            Assert.AreEqual(Cardinality.Single, dmRelationship.Cardinality);
            Assert.AreEqual(Cardinality.Single, dmRelationship.ReverseRelationship.Cardinality);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

       [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_SingleWhenSingleReverse_NoReversRelProps_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = CreateClassWithAKAndRelationship();
            DMRelationship dmRelationship = dmClass.OwnerRelationships[0];
            DMClass relatedClass = CreateClassWithPKAndRelationship_NoRelProps();
            SetReverseRelationship(dmRelationship, relatedClass.OwnerRelationships[0]);
//            dmRelationship.ReverseRelationship = relatedClass.OwnerRelationships[0];
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(relatedClass.ObjectIdentity);
            Assert.IsNull(dmClass.ObjectIdentity);
            Assert.AreEqual(1, dmClass.UniqueConstraints.Count);
            Assert.AreEqual(Cardinality.Single, dmRelationship.Cardinality);
            Assert.AreEqual(Cardinality.Single, dmRelationship.ReverseRelationship.Cardinality);
            Assert.AreEqual(0, ((DMRelationship)dmRelationship.ReverseRelationship).RelationshipProperties.Count);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_SingleWhenSingleReverse_NoRelatedClass_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = CreateClassWithPKAndRelationship();
            DMRelationship dmRelationship = dmClass.OwnerRelationships[0];
            SetReverseRelationship(dmRelationship, new DMRelationship());
            dmRelationship.ReverseRelationship.Cardinality = Cardinality.Single;
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNull(dmRelationship.ReverseRelationship.ClassDM);
            Assert.IsNotNull(dmClass.ObjectIdentity);
            Assert.AreEqual(Cardinality.Single, dmRelationship.Cardinality);
            Assert.AreEqual(Cardinality.Single, dmRelationship.ReverseRelationship.Cardinality);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_MultipleWhenInPK_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = CreateClassWithPKAndRelationship();
            DMRelationship dmRelationship = dmClass.OwnerRelationships[0];
            dmRelationship.Cardinality = Cardinality.Multiple;
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmClass.ObjectIdentity);
            Assert.AreEqual(0, dmClass.UniqueConstraints.Count);
            Assert.AreEqual(Cardinality.Multiple, dmRelationship.Cardinality);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_MultipleWhenInAK_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = CreateClassWithAKAndRelationship();
            DMRelationship dmRelationship = dmClass.OwnerRelationships[0];
            dmRelationship.Cardinality = Cardinality.Multiple;
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNull(dmClass.ObjectIdentity);
            Assert.AreEqual(1, dmClass.UniqueConstraints.Count);
            Assert.AreEqual(Cardinality.Multiple, dmRelationship.Cardinality);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_MultipleWhenInInheritedPK_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty();
            DMClass superClass = (DMClass) dmProperty.Class;
            superClass.CreateObjectIdentity(dmProperty);
            DMClass subClass = new DMClass();
            DMInheritanceRelationship inheritanceRelationship = new DMInheritanceRelationship();
            inheritanceRelationship.SuperClass = superClass;
            subClass.InheritanceSuperClassRelationship = inheritanceRelationship;

            DMRelationship dmRelationship = new DMRelationship();
            subClass.OwnerRelationships.Add(dmRelationship);
            DMRelationshipProperty relationshipProperty = dmRelationship.RelationshipProperties.CreateBusinessObject();
            relationshipProperty.Property = dmProperty;

            dmRelationship.Cardinality = Cardinality.Multiple;
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNull(subClass.ObjectIdentity);
            Assert.IsNotNull(superClass.ObjectIdentity);
            Assert.AreEqual(0, subClass.UniqueConstraints.Count);
            Assert.AreEqual(0, superClass.UniqueConstraints.Count);
            Assert.AreEqual(Cardinality.Multiple, dmRelationship.Cardinality);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_MultipleWhenInInheritedAK_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty();
            DMClass superClass = (DMClass) dmProperty.Class;
            superClass.CreateUnsavedUniqueConstraint(new List<DMProperty> {dmProperty});
            
            DMClass subClass = new DMClass();
            DMInheritanceRelationship inheritanceRelationship = new DMInheritanceRelationship();
            inheritanceRelationship.SuperClass = superClass;
            subClass.InheritanceSuperClassRelationship = inheritanceRelationship;

            DMRelationship dmRelationship = new DMRelationship();
            subClass.OwnerRelationships.Add(dmRelationship);
            DMRelationshipProperty relationshipProperty = dmRelationship.RelationshipProperties.CreateBusinessObject();
            relationshipProperty.Property = dmProperty;

            dmRelationship.Cardinality = Cardinality.Multiple;
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, subClass.UniqueConstraints.Count);
            Assert.AreEqual(1, superClass.UniqueConstraints.Count);
            Assert.AreEqual(Cardinality.Multiple, dmRelationship.Cardinality);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_DMRelationshipOnetoOneAndManytoOnePropKeyRule_WhenNoClass_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMRelationship dmRelationship = new DMRelationship();
            IBusinessObjectRule rule = new DMRelationshipOnetoOneAndManytoOnePropKeyRule();
            //---------------Assert Precondition----------------
            Assert.IsNull(dmRelationship.ClassDM);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        private DMClass CreateClassWithAKAndRelationship()
        {
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty();
            DMClass dmClass = (DMClass) dmProperty.Class;
            DMRelationship dmRelationship = new DMRelationship();
            dmClass.OwnerRelationships.Add(dmRelationship);
            DMRelationshipProperty relationshipProperty = dmRelationship.RelationshipProperties.CreateBusinessObject();
            relationshipProperty.Property = dmProperty;
            DMUniqueConstraint uniqueConstraint = dmClass.UniqueConstraints.CreateBusinessObject();
            uniqueConstraint.AddPropertyInfo(dmProperty);
            return dmClass;
        }

        private DMClass CreateClassWithPKAndRelationship()
        {
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty();
            DMClass dmClass = (DMClass) dmProperty.Class;
            dmClass.CreateObjectIdentity(dmProperty);
            DMRelationship dmRelationship = new DMRelationship();
            dmClass.OwnerRelationships.Add(dmRelationship);
            DMRelationshipProperty relationshipProperty = dmRelationship.RelationshipProperties.CreateBusinessObject();
            relationshipProperty.Property = dmProperty;
            return dmClass;
        }

        private DMClass CreateClassWithPKAndRelationship_NoRelProps()
        {
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty();
            DMClass dmClass = (DMClass) dmProperty.Class;
            dmClass.CreateObjectIdentity(dmProperty);
            DMRelationship dmRelationship = new DMRelationship();
            dmClass.OwnerRelationships.Add(dmRelationship);
            return dmClass;
        }

        #endregion
    }
}